<?php
/**
 * users
 *
 * @version:	0.1
 * @package:	global
 * @author:	alex_ez
 * @created:	31.01.2010 01:23
 *
 * @copyright:	(c) 2010 alex <qfox@ya.ru> yaroshevich aka alex_ez. All rights reserved.
 */


class usersAdminController extends adminController
{
	protected $rootUrl;
	
	static public function getMenuItems( )
	{
		return json::decode( '{"users":{"text":"Users","group":"Система"}}' );
	}
	
	private $fields;
	
	private $users = null;
	protected $lists = array(
		'states' => array( 'newbie' => 'Неавторизованный', 'person' => 'Полноценный', 'frozen' => 'Остановленный' ),
		);
	
	public function onstart( )
	{
		$this ->visitor = visitor::__getMe( );
		$this ->visitor ->needAuth( 'admin' );
		$this ->frame = 'admin/!index.tpl';
		$this ->users = new users( );
		$this ->rootUrl = '/admin/'.str_replace( array( 'AdminController', '_' ), array( '', '/' ), get_class( $this ) ).'/';
	}
	
	// /admin/users/
	public function showIndexPage( $p, $o )
	{
		$r = array( );
		
		$o = strtolower( (string)( Request::__getMe( ) ->g_order ) );
		$d = substr( $o, -1, 1 ) == '-' ? '-' : '+';
		$o = ( strpos( ',login,name,id,', ','.trim($o,'+-').',' ) === false ) ? 'name' : trim($o,'+-');
		
		
		// filter
		$filter = new filter( $this, 'users', array( 'action' => './', 'mode' => 'limited', 'limits' => '20,50,100,200,500' ) );
		$filter ->setData( array( 'limit' => 1 ) );
		$filter ->setLists( $this ->lists );
		$r['filter'] = $filter ->getFormData( );
		$w = $filter ->getWhereData( );
		
		// limit with no paging
		$limit = array( 0, $filter ->getLimitValue( ) );
		
		// store for remove
		$this ->visitor ->storedquery = $filter ->getQuery( array( 'order' => $o.$d ) );
		
		//$r['cols'] = "Логин|Организация|Контактные данные[Телефон|Почта|Адрес]|Описание|Служебные данные[#|Регистрация|IP|Статус]";
		$__q = $filter ->getQuery( ); $__q .= !empty($__q)?'&':'';
		$r['cols'] = 'Login'.($o=='login'?' '.($d=='+'?'↓':'↑'):'').'::href=?'.$__q.'order=login'.($o=='login'&&$d=='+'?'-':'').($o=='login'?':class=common':'')
			.'|Account data[Name'.($o=='name'?' '.($d=='+'?'↓':'↑'):'').'::href=?'.$__q.'order=name'.($o=='name'&&$d=='+'?'-':'').($o=='name'?':class=common':'').'|Email|Phone]'
			.'|System data[#'.($o=='id'?' '.($d=='+'?'↓':'↑'):'').'::href=?'.$__q.'order=id'.($o=='id'&&$d=='+'?'-':'').($o=='id'?':class=common':'').'|Signup|Roles|IP|Pwd::title=Change password]'
			."|Addit::title=Additional comments";
		
		$o = $o=='name'?('surname'.$d.','.$o.$d):($o.$d);
		$items = array( );
		foreach( $this ->users ->getBy( $w, '`surname` like "∫%"'.($d=='+'?'-':'+').','.$o, $limit ) as $id => $user )
		{
			$passchange = $this ->users ->getPasswordChanges( $id );
			
			$item = array( );
			foreach( array( 'login', 'name', /*'surname', */'email', 'phone', /*'address',*/ 'id', 'tm', 'roles', 'ip', 'password', 'desc' ) as $k )
				$item[$k] = ( isset( $user[$k] ) ) ? $user[$k] : '—';
			
			$item['name'] = sprintf( '%s %s %s', $user['surname'], $item['name'], $user['patronymic'] );
			$item['tm'] = $item['tm']>0 ? date( 'd.m.Y', strtotime( $item['tm'] ) ) : '—';
			$item['login'] = sprintf( '<span title="%2$s" style="background:#777;color:white;font-weight:bold;">&nbsp;%1$s&nbsp;</span> ', strtoupper($user['state'][0]), $user['state'] )
				.sprintf( '<a href="'.($this->rootUrl).'edit/?id=%d">%s</a>', $user['id'], $user['login'] );
			$item['email'] = sprintf( '<a href="mailto:%1$s" class="email">%1$s</a>', $user['email'] );
			$item['password'] = sprintf( '<a href="'.($this->rootUrl).'editpassword/?id=%d" class="button edit confirm" target="_blank" title="Сменить пароль"></a>', $user['id'] );
			
			if( !is_null( $passchange ) )
			{
				$lastpasschange = is_null( $passchange ) ? '—' : reset( $passchange );
				$item['password'] .= count($passchange)>1?sprintf(' %d изм.; %s',count($passchange)-1,date('d.m.Y, H:i',strtotime($lastpasschange['tm']))):' Не изменялся';
			}
			
			$items[$id] = $item;
		}
		
		$r['items'] = $items;
		$r['count'] = $this ->users ->getFoundRows( );
		$r['template'] = 'admin/__list.tpl';
		$r['title'] = texo::translate('Users');
		
		return $r;
	}
	
	// /admin/users/editpassword/
	public function showEditpasswordPage( $p, $o )
	{
		$id = (int)(Request::__getMe( ) ->g_id);
		if( $id <= 0 ) response::__getMe()->moved( ($this->rootUrl) );
		$user = $this ->users ->get( $id );
		if( !$user ) response::__getMe()->moved( ($this->rootUrl) );
		
		$title = sprintf( _('Change password for account «%s»'), $user['login'] );
		$this ->title = $title;
		
		$r = sprintf( '<h1>%s</h1>', $title );
		
		$newpass = strtolower( str_shuffle( substr( preg_replace( '/[^a-z0-9]/i', '', base64_encode( sha1( microtime(1), 1 ) ) ), 0, rand(8,11) ) ) );
		$formc = sprintf( '<label>Новый пароль:</label> <input type="text" name="pass" value="%s" /><br/>', $newpass );
		
		$formc .= '<input type="submit" value="Сохранить новый пароль" style="background:#f99;" />';
		$formc .= '<button onclick="window.location=window.location;return false;" style="background:#99f;">Сгенерировать другой</button>';
		$formc .= '<button onclick="window.close();">Отмена</button>';
		
		$r .= sprintf( '<form action="./done/?id=%d" method="post">%s</form>', $user['id'], $formc );
		
		return $r;
	}

	// /admin/users/editpassword/
	public function showEditpassword_donePage( $p, $o )
	{
		$id = (int)(Request::__getMe( ) ->g_id);
		if( $id <= 0 ) response::__getMe()->moved( ($this->rootUrl) );
		$user = $this ->users ->get( $id );
		if( !$user ) response::__getMe()->moved( ($this->rootUrl) );
		
		$newpass = Request::__getMe( ) ->p_pass;
		if( !$newpass ) response::__getMe()->moved( ($this->rootUrl).'editpassword/?id='.$user['id'] );
		
		$this ->users ->editPassword( $user['id'], $newpass );
		
		$r = array( );
		$r['login'] = $user['login'];
		$r['frame'] = '!print.tpl';
		$r['password'] = $newpass;
		$r['title'] = _('New password for account');
		
		return $r;
	}
	
	

	// /admin/users/add/
	public function showAddPage( $p, $o )
	{
		$r = array( );
		
		$form = new form( $this, 'add' );
		$form ->setOption( 'name', 'adduser' );
		$form ->setOption( 'action', '/ajax'.($this->rootUrl).'add/' );
		
		// send form to template
		$r['fields'] = $form ->getFieldSet( );
		$r['options'] = $form ->getOptions( );
		$r['title'] = _('Create an account');
		$r['template'] = 'admin/__form.tpl';
		
		return $r;
	}
	
	public function ajaxAdd( $z )
	{
		// fetch post data & if data is bogus return error
		$form = new Form( $this, 'add' );
		try { $p = $form ->getPostData( ); } catch( FormException $e ) { return array( 'error' => $e ->getMessage( ) ); }
		
		$p['state'] = 'person';
		$p['password'] = strtolower(substr(base64_encode(sha1(microtime(1),1)),0,rand(6,9)));
		$id = $this ->users ->add( $p );
		if( $id<=0 ) return array( 'error' => _('Account already exists') );
		$r = $this ->users ->edit( $id, $p );
		if( $r<=0 ) return array( 'error' => _('Account not created') );
		
		return array( 'location' => ($this->rootUrl).'edit/?id='.$id, 'message' => _('Data stored!')."\n".sprintf( _('Please save temporary password: %s'), $p['password'] )."\n"._('Don‘t forget to fill account information!') );
	}
	
	// /admin/users/edit/
	public function showEditPage( $p, $o )
	{
		$id = (int)(Request::__getMe( ) ->g_id);
		if( $id == -1 ) response::__getMe()->moved( ($this->rootUrl).'add/' );
		if( $id <= 0 ) response::__getMe()->moved( ($this->rootUrl) );
		$user = $this ->users ->get( $id );
		if( !$user ) response::__getMe()->moved( ($this->rootUrl) );
		
		$r = array( );
		
		$form = new form( $this, 'edit' );
		$form ->setOption( 'name', 'edituser' );
		$form ->setOption( 'action', '/ajax'.($this->rootUrl).'edit/?id='.$user['id'] );
		$data = $user;
		$data['login'] .= sprintf( ' <sup><a href="'.($this->rootUrl).'editpassword/?id=%d" title="%s">%s</a></sup>',
			$user['id'],
			sprintf( _('Change password for account «%s»'), $user['login'] ),
			_('change password') );
		$data['tm'] = date( 'd.m.Y, H:i', strtotime($data['tm']) );
		$data['birthday'] = date_format( date_create( $data['birthday'] ), 'd.m.Y' );
		
		$form ->setData( $data );
		
		// send form to template
		$r['fields'] = $form ->getFieldSet( );
		$r['options'] = $form ->getOptions( );
		$r['title'] = _('Account').' '.$user['login'];
		$r['template'] = 'admin/__form.tpl';
		
		return $r;
	}
	
	
	
	public function ajaxEdit( $z )
	{
		$id = (int)(Request::__getMe( ) ->g_id);
		if( $id <= 0 ) return array( 'error' => 'invalid user' );
		$user = $this ->users ->get( $id );
		if( !$user ) return array( 'error' => 'invalid user' );
		
		// fetch post data & if data is bogus return error
		$form = new Form( $this, 'edit' );
		try { $p = $form ->getPostData( ); } catch( FormException $e ) { return array( 'error' => $e ->getMessage( ) ); }
		
		// update user item
		try { $birthday = new DateTime( $p['birthday'] ); } catch( FormException $e ) { return array( 'error' => 'Разрешенный формат для поля день рождения ДД.ММ.ГГГГ' ); }
		$p['birthday'] = $birthday ->format( 'Y-m-d' );
		
		$r = $this ->users ->edit( $user['id'], $p );
		if( $r<0 ) return array( 'error' => _('Data not stored') );
		
		return array( 'location' => ($this->rootUrl), 'message' => _('Data stored!') );
	}
	
	
	private $fieldSets = array(
'add' =>
"{'head':	{type:'header',	label:'Общие данные'},
'login':	{type:'string',	label:'Логин'},
'surname':	{type:'string',	label:'Фамилия',required:true},
'name':		{type:'string',	label:'Имя',required:true},
'patronymic':	{type:'string',	label:'Отчество'},
}",

'edit' =>
"{'head':	{type:'header',	label:'Общие данные'},
'tm':		{type:'static',	label:'Дата регистрации',readonly:true},
'login':	{type:'static',	label:'Логин'},
'surname':	{type:'string',	label:'Фамилия',required:true},
'name':		{type:'string',	label:'Имя',required:true},
'patronymic':	{type:'string',	label:'Отчество'},
'addhead':	{type:'header',	label:'Дополнительные'},
'birthday':	{type:'date',	label:'Дата рождения',value:'01.01.1900','donttouch':1},
'email':	{type:'email',	label:'Почта',required:true},
'phone':	{type:'phone',	label:'Телефон'},
'roles':	{type:'string',	label:'Роли',class:'withfast fastlist:manager,developer'},
'desc':		{type:'text',	label:'Комментарий'},
}",

'users#filter' =>
"{'head':	{type:'header',	label:''},
'login':	{type:'string',	label:'Логин'},
'surname':	{type:'string',	label:'Фамилия'},
'name':		{type:'string',	label:'Имя'},
'patronymic':	{type:'string',	label:'Отчество'},
'id':		{type:'number',	label:'ID'},
'tm':		{type:'date',	label:'Регистрация',period:true},
'state':	{type:'list',	label:'Состояние',values:'states',null:true},
}",

);
	
	public function getFieldSet( $url = null, $decode = false )
	{
		$iurl = !is_null( $url ) ? $url : $this ->getInnerUrl( );
		$r = isset( $this ->fieldSets[ $iurl ] ) ? $this ->fieldSets[ $iurl ] : ''; //json::decode( $fields );
		
		$replacements = array(
			'now' => date('d.m.Y'),
			'yesterday' => date('d.m.Y',time()-86400),
			'tomorrow' => date('d.m.Y',time()+86400),
			'user.login' => visitor::__getMe() ->user['login'],
			);
		
		// replacing
		$r = str_replace(
			array_map( create_function('$v','return "{{$v}}";'), array_keys( $replacements ) ),
			array_values( $replacements ),
			$r );
		
		return $decode ? json::decode( $r ) : $r;
	}

}


?>